#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>

int useful_ip_count = 0;
char *useful_ip[252] = {0};
char ip_net[128] = {0};

pthread_mutex_t data_mutex = PTHREAD_MUTEX_INITIALIZER;
#define  DATA_LOCK        do{pthread_mutex_lock(&data_mutex);} while (0)
#define  DATA_UNLOCK    do{pthread_mutex_unlock(&data_mutex);} while (0)

void get_ip_net();
//void * TestIp(void *args); 一直以为线程函数是这种空指针函数，其实任何函数都可以，该例子用了整型函数一样可以获取正确结果
void* TestIp(void *args);
void sort_ip_asc();

int main(int argc, char **argv) {
    
    time_t ts,tf;
    ts=time(NULL);
    
    int ret=0;
    int i;
    char test_ip[64] = {0};
    pthread_t pid[255];
    
    get_ip_net();
    
    if (strlen(ip_net)<6)
        exit(-1);
    
    for (i=2;i<255;i++)
    {
        memset(test_ip, 0, 64);
        sprintf(test_ip,"%s%d",ip_net,i);
        //if ((ret=pthread_create(&pid[i], NULL, (void *)TestIp, (void *)strdup(test_ip))) !=0)
        if ((ret=pthread_create(&pid[i], NULL, &TestIp, (void *)strdup(test_ip))) !=0)
        {
            printf("create pthread failed, pid NO. is %d;error NO. is %d.\n", i, ret);
        }
    }
    
    for (i=2;i<255;i++)
    {
        pthread_join(pid[i], NULL);
    }
    
    printf("This local net has %d useful ip:\n",useful_ip_count);
    sort_ip_asc();
    for (i=0;i< useful_ip_count;i++)
    {
        printf(" %d: %s\n", i, useful_ip[i]);
    }
    
    for (i=0;i< useful_ip_count;i++)
    {
        if(useful_ip[i] != NULL)
            free(useful_ip[i]);
    }
    
    tf=time(NULL);
    printf("Time cost:%d second\n",(int)(tf-ts));
    return 0;
}

void get_ip_net(){
    
    char tmp[256] = {0};
    char *p          = NULL;
    
    strcpy(tmp,"route -n |grep UG |awk '{print $8}'|xargs ifconfig |grep \"inet addr:\" |awk '{print $2}' |awk -F: '{print $2}' >/root/ip.dat");
    
    if(strlen(tmp)>0 && !system(tmp)) {
        FILE *Fp = fopen("/root/ip.dat","r");
        if (Fp != NULL)
        {
            fgets(ip_net, 127, Fp);
            fclose(Fp);
            
            p=strrchr(ip_net, '.');
            if (p != NULL)
                *(p+1)='\0';
        }
    }
}

//void *TestIp(void *args) {
//    char tmp[128] = {0};
//    char *ip      = NULL;
//
//    ip = (char *)args;
//    sprintf(tmp,"ping -c 2 %s >/dev/null 2>&1", ip);
//    if (!system(tmp))
//    {
//        DATA_LOCK;
//        useful_ip[useful_ip_count] = strdup(ip);
//        useful_ip_count++;
//        DATA_UNLOCK;
//    }
//
//    if(ip != NULL)
//        free(ip);
//
//    return NULL;
//}

void* TestIp(void *args) {
    char tmp[128] = {0};
    char *ip      = NULL;
    
    ip = (char *)args;
    sprintf(tmp,"ping -c 2 %s >/dev/null 2>&1", ip);
    if (!system(tmp))
    {
        DATA_LOCK;
        useful_ip[useful_ip_count] = strdup(ip);
        useful_ip_count++;
        DATA_UNLOCK;
    }
    
    if(ip != NULL)
        free(ip);
    
    return nullptr;
}

void sort_ip_asc(){
    
    int i, j, lastSwap;
    int p1,p2;
    char *tmp = NULL;
    char *p      = NULL;
    
    for (j=useful_ip_count-1; j>0; j=lastSwap) {
        lastSwap=0;     //每一轮要初始化为0，防止某一轮未发生交换，lastSwap保留上一轮的值进入死循环
        for (i=0; i<j; i++) {//get a max number one for loop
            if (useful_ip[i] == NULL || useful_ip[i+1] == NULL)
                break;
            
            p=strrchr(useful_ip[i], '.');
            p1=atoi(p+1);
            
            p=strrchr(useful_ip[i+1], '.');
            p2=atoi(p+1);
            
            if (p1 > p2) {
                tmp                = useful_ip[i];
                useful_ip[i]    = useful_ip[i+1];
                useful_ip[i+1]  =tmp;
                //最后一次交换位置的坐标
                lastSwap = i;
            }
        }
    }
}
